package erfgame.core.world.generator.terrain;


import erfgame.core.Operation;
import erfgame.core.Point3D;
import erfgame.core.SimpleAbstractOperation;
import erfgame.core.dao.ObjectDAO;
import erfgame.core.memory.MemoryPool;
import erfgame.core.memory.Pointer;
import erfgame.core.world.World;
import erfgame.core.world.WorldDAOManager;
import erfgame.core.world.WorldGenerationParameters;
import erfgame.core.world.WorldGenerator;

public class TerrainBlockWorldGenerator implements WorldGenerator {
	
	private WorldDAOManager terrainDAOManager;
	private TerrainBlockGenerator generator;
	private MemoryPool<byte[][][]> memoryPool;

	public TerrainBlockWorldGenerator( WorldDAOManager daoManager, TerrainBlockGenerator generator, MemoryPool<byte[][][]> memoryPool ) {
		this.terrainDAOManager = daoManager;
		this.generator = generator;
		this.memoryPool = memoryPool;
	}
	
	public Operation<Void,RuntimeException> generate(final World world, final WorldGenerationParameters parameters) {
		return new SimpleAbstractOperation<Void,RuntimeException>("creating terrain") {

			public Void doPerform() throws RuntimeException {
				ObjectDAO<Point3D, Pointer<byte[][][]>> blockTerrainDAO = terrainDAOManager.getBlockTerrainDAO( world );
				
				int blockWidth = world.getBlockWidth();
				int blockHeight = world.getBlockHeight();
				int blockDepth = world.getBlockDepth();
				
				// for each block generate the world 
				for( int x=world.getBlocksX(); x>0; ) {
					x--;
					for( int y=world.getBlocksY(); y>0; ) {
						y--;
						for( int z=world.getBlocksZ(); z>0; ) {
							z--;
							Pointer<byte[][][]> terrain = memoryPool.claim(false).createPointer();
							if( generator.generate(x, y, z, blockWidth, blockHeight, blockDepth, terrain.getValue() ) ) {
								blockTerrainDAO.storeObject( new Point3D(x, y, z), terrain );
							}
							terrain.free();
						}
					}
				}
				return null;
			}
		};
	}
}
